home *** CD-ROM | disk | FTP | other *** search
/ ADA Programming Guide / ADA Programming Guide.iso / ada_gwu / makecorr.c < prev    next >
C/C++ Source or Header  |  1996-01-30  |  12KB  |  504 lines

  1. /*
  2.  * Copyright (C) 1985-1992  New York University
  3.  * 
  4.  * This file is part of the Ada/Ed-C system.  See the Ada/Ed README file for
  5.  * warranty (none) and distribution info and also the GNU General Public
  6.  * License for more details.
  7.  
  8.  */
  9. #include "hdr.h"
  10. #include "ada.h"
  11. #include "adalexp.h"
  12. #include "pspansp.h"
  13. #include "prsutilp.h"
  14. #include "errsp.h"
  15. #include "lookupp.h"
  16. #include "recoverp.h"
  17. #include "makecorp.h"
  18.  
  19. static void reset_cands();
  20.  
  21. Span_s PRSERR_LOC ;
  22.  
  23.  
  24. void make_correction(struct two_pool *STATE_STACK)        /*;make_correction*/
  25. {
  26.     /* Choose a correction by trying the modes in the order: merge, spelling,
  27.      * insertion, deletion, substitution.  
  28.      * Generate appropriate error message.
  29.      * Apply corrective action to token sequence, and restore state and parse
  30.      * stacks to correction point.
  31.      */
  32.     struct    prsstack *ct,*nt,*r,*tokmod,*curtoken ;
  33.     struct    two_pool *tmp_tp ;
  34.     int    i ;
  35.     char    *tv,*ctv,*ntv ;
  36.     int        intok,subtk,bk ;
  37.     int        n_STATE_STACK ;
  38.     char    msg[200];
  39.     int    delete_flag = 0;
  40.  
  41.     /************************** M E R G E *********************************/
  42.  
  43.     if ( CANDIDATES[MERGE] != NULL ) {
  44.  
  45.         /* [subtk, bk] := arb CANDIDATES[MERGE];                            
  46.          * This will be achieved by taking the first element of the list    
  47.          */
  48.  
  49.         tv = namelist( subtk = CANDIDATES[MERGE]->token_sym ) ;
  50.  
  51.         /*    ct = bk == 0 ? curtok : PREVTOK ; */
  52.  
  53.         if((bk = CANDIDATES[MERGE]->backup_toks) == 0)
  54.             ct = copytoken(curtok) ;
  55.         else
  56.             ct = copytoken(PREVTOK) ;
  57.  
  58.         /*     nt =  bk == 0 ? nexttok : curtok ; */
  59.         if(bk == 0)
  60.             nt = copytoken(nexttok) ;
  61.         else
  62.             nt = copytoken(curtok) ;
  63.  
  64.         ctv = namelist(ct->ptr.token->index);
  65.         ntv = namelist(nt->ptr.token->index);
  66.  
  67.         /* PRSERR_LOC = position(ct); */
  68.         PRSERR_LOC = ct->ptr.token->span ;
  69.         sprintf(msg,"\"%s\" expected instead of \"%s\" \"%s\"",
  70.           tv,ctv,ntv) ;
  71.         syntax_err(LLOC(ct),RLOC(nt),msg);
  72.  
  73.         for (i = 1 ; i <= bk ; i++) {
  74.             r = prs_stack ;
  75.             prs_stack = prs_stack->prev ;
  76.             add_to_top(r) ;
  77.         } 
  78.  
  79.         /*
  80.          * tokens[tokind - 1 ] = [[subtk, namemap(token_value_des(tv) ? tv),
  81.          *                        top(ct)]];
  82.          */
  83.          TOKMINUS ;
  84.          tokens[tokind]->symbol = subtk ;
  85.          tokens[tokind]->ptr.token->index = namemap(tv,strlen(tv));
  86.          tokens[tokind]->ptr.token->span = ct->ptr.token->span ;
  87.  
  88.  
  89.         /*    
  90.          *    STA_STACK +:= STATE_STACK(n_STA_STACK + 1 ..
  91.          *                                    n_STATE_STACK - bk);
  92.          */
  93.  
  94.  
  95.         /*    Strip bk elements off the top off STATE_STACK    */
  96.  
  97.         while( bk-- > 0)
  98.             STATE_STACK = STATE_STACK->link ;
  99.  
  100.         /* Count the size of STATE_STACK */
  101.  
  102.         n_STATE_STACK = 0 ;
  103.         tmp_tp = STATE_STACK ;
  104.         while (tmp_tp != NULL) {
  105.             n_STATE_STACK ++ ;
  106.             tmp_tp = tmp_tp->link ;
  107.         }
  108.  
  109.         /* Count the size of STATE_STACK */
  110.  
  111.         n_sta_stack = 0 ;
  112.         tmp_tp = sta_stack ;
  113.         while (tmp_tp != NULL) {
  114.             n_sta_stack ++ ;
  115.             tmp_tp = tmp_tp->link ;
  116.         }
  117.  
  118.         /*    Put the top (n_STATE_STACK - n_sta_stack) elements of STATE_STACK
  119.          *  on the end of sta_stack
  120.          */
  121.          i = n_STATE_STACK - n_sta_stack ;
  122.          tmp_tp = STATE_STACK ;
  123.          while (--i > 0 )
  124.             tmp_tp = tmp_tp->link ;
  125.          tmp_tp->link = sta_stack ;
  126.          sta_stack = STATE_STACK ;
  127.  
  128.         reset_cands() ;
  129.         return;
  130.     }    /* if */
  131.  
  132.     /************************** S P E L L   S U B S T *********************/
  133.  
  134.     else if (CANDIDATES[SPELL_SUBST] != NULL ) {
  135.  
  136.  
  137.         /* [subtk, -, bk] := CANDIDATES[SPELL_SUBST]; */
  138.  
  139.         tv = namelist((subtk = CANDIDATES[SPELL_SUBST]->token_sym ));
  140.  
  141.         /* ct = bk == 0 ? curtok : prs_stack(n_prs_stack - bk + 1) ; */
  142.     
  143.         if ((bk = CANDIDATES[SPELL_SUBST]->backup_toks) == 0) {
  144.             ct = copytoken(curtok) ;
  145.         }
  146.         else {
  147.             /* ct := prs_stack(n_prs_stack - bk + 1) */ 
  148.             int    bktmp = bk ;
  149.             ct = prs_stack ;
  150.             while(--bktmp)
  151.                 ct = ct->prev ;
  152.             ct->prev = NULL ;
  153.         }
  154.         /* PRSERR_LOC := position(ct); */
  155.         PRSERR_LOC = ct->ptr.token->span ;
  156.  
  157.         /* tokmod := [[subtk, tv, top(ct)]]; */
  158.         tokmod = ct ;
  159.         tokmod->prev = NULL ;
  160.         tokmod->symbol = subtk ;
  161.         /* tokmod->ptr.token->index = tv ; */
  162.         tokmod->ptr.token->span = ct->ptr.token->span ; 
  163.  
  164.         sprintf(msg , "Reserved word \"%s\" misspelled", tv ) ;
  165.         syntax_err(LLOC(ct),RLOC(ct),msg);
  166.     }
  167.  
  168.     /***************************** I N S E R T *******************************/
  169.  
  170.     else if (CANDIDATES[INSERT] != NULL ) {
  171.         
  172.         Span_s pt,ct ;
  173.         struct  prsstack *pt_token;
  174.         short        tmp_symbol ;
  175.  
  176.  
  177.         /* [intok, -, bk] := arb CANDIDATES[INSERT]; */
  178.  
  179.         tv = namelist((intok = CANDIDATES[INSERT]->token_sym));
  180.  
  181.         /* curtoken := bk == 0 ? curtok : prs_stack(n_prs_stack - bk + 1) ; */
  182.  
  183.         if ((bk = CANDIDATES[INSERT]->backup_toks) == 0) {
  184.             curtoken = copytoken(curtok) ;
  185.         }
  186.         else {
  187.             /* curtoken := prs_stack(n_prs_stack - bk + 1) */ 
  188.             int    bktmp = bk ;
  189.  
  190.             struct prsstack *tmp_ps = prs_stack ;
  191.  
  192.             while(--bktmp)
  193.                 tmp_ps = tmp_ps->prev ;
  194.  
  195.             pt =  r_span(tmp_ps->prev) ;
  196.             tmp_symbol = tmp_ps->prev->symbol ;
  197.             /* copytoken(curtoken,tmp_ps) ; */
  198.             curtoken = tmp_ps;
  199.             pt_token = curtoken->prev;
  200.         }
  201.  
  202.         if (bk == 0) {
  203.             /* pt =     r_span(prs_stack) ; */
  204.             /* if parse stack is empty (error on first token),
  205.                use location of current token  */
  206.             /* Metaware HIC does not like next line - so expand it manually 
  207.                 pt = (prs_stack != (struct prsstack *)0
  208.                   ? r_span(prs_stack)
  209.                 : l_span(curtoken) ) ;
  210.              */
  211.             if (prs_stack != (struct prsstack *)0) {
  212.                 pt = r_span(prs_stack);
  213.                 pt_token = prs_stack;
  214.             }
  215.             else {
  216.                 pt = l_span(curtoken);
  217.                 pt_token = curtoken;
  218.             }
  219.             tmp_symbol = prs_stack->symbol ;
  220.         }
  221.  
  222.         ct = l_span(curtoken) ;
  223.  
  224.         for (i = 1 ; i <= bk; i++ ) {
  225.             r = prs_stack;
  226.             prs_stack = prs_stack->prev ;
  227.             add_to_top(r) ;
  228.         } 
  229.         /* 
  230.          *    tokmod := [curtoken, [intok, get_name(token_value_des(tv) 
  231.          *                    ? tv), top(pt)]];                             
  232.          */
  233.  
  234.         /* curtoken->prev = TALLOC() ; */
  235.         /* curtoken->prev->ptr->index = namemap(tv) ; */
  236.         /* curtoken->prev->ptr.token->span = pt->ptr->span ; */
  237.         tokens[tokind] = curtoken ;
  238.  
  239.         add_to_top(PRSALLOC()) ;
  240.         tokens[tokind]->symbol = intok ;
  241.         tokens[tokind]->ptr.token = TOKALLOC() ;
  242.         tokens[tokind]->ptr.token->index = namemap((char *)token_val_des(tv),
  243.                                             strlen((char *)token_val_des(tv))) ;
  244.         tokens[tokind]->ptr.token->span = pt ;
  245.         tokmod = NULL;        
  246.  
  247.  
  248.         if (n_CANDIDATES[INSERT] == 1) {
  249.  
  250.             if (( tmp_symbol == SEMI_SYM  )
  251.               || (prs_stack == NULL) /* if parse stack empty */
  252.               || ( tmp_symbol > EOFT_SYM ) ) {
  253.                 /*
  254.                 * This kludge is to take
  255.                 * care of nonterminals
  256.                 */
  257.                 sprintf(msg,"\"%s\" expected before this token",tv);
  258.                 /*
  259.                 syntax_err(&PREVTOK->ptr.token->span,
  260.                   &PREVTOK->ptr.token->span,msg);
  261.                 */
  262.                 syntax_err(LLOC(curtoken),RLOC(curtoken),msg) ;
  263.                 PRSERR_LOC = ct ;
  264.             }
  265.             else {
  266.                 PRSERR_LOC = pt ;
  267.                 sprintf(msg,"\"%s\" expected after this token",tv);
  268.                 syntax_err(LLOC(pt_token),RLOC(pt_token),msg) ;
  269.                 /*
  270.                 syntax_err(&PREVTOK->ptr.token->span,
  271.                   &PREVTOK->ptr.token->span,msg);
  272.                 syntax_err(&curtok->ptr.token->span,&curtok->ptr.token->span,msg);
  273.                 */
  274.             }
  275.         }
  276.         else {
  277.             PCAND    next_cand ;
  278.             char *tmp = msg;
  279.             /* 
  280.              * errfile := [
  281.              *     '{' +/[' ' + NAME_LIST(x(1)) : x in inserts] 
  282.              *            + ' } expected after this token'];
  283.              */
  284.  
  285.             sprintf(tmp,"One of { ");
  286.             tmp += strlen(tmp);
  287.             next_cand = CANDIDATES[INSERT] ;
  288.             while(next_cand != NULL) {    
  289.                 sprintf(tmp,"%s ",namelist(next_cand->token_sym) ) ;
  290.                 tmp += strlen(tmp);
  291.                 next_cand = next_cand->next ;
  292.             }
  293.  
  294.             sprintf(tmp," } expected after this token");
  295.             PRSERR_LOC = pt ;
  296.             syntax_err(LLOC(pt_token),RLOC(pt_token),msg);
  297.         }
  298.  
  299.         /* 
  300.          * STA_STACK +:= STATE_STACK(n_STA_STACK + 1 .. n_STATE_STACK - bk) ; 
  301.          */
  302.  
  303.         /*    Strip bk elements off the top off STATE_STACK    */
  304.  
  305.         while(bk--)
  306.             STATE_STACK = STATE_STACK->link ;
  307.  
  308.         /* Count the size of STATE_STACK */
  309.  
  310.         n_STATE_STACK = 0 ;
  311.         tmp_tp = STATE_STACK ;
  312.         while (tmp_tp != NULL) {
  313.             n_STATE_STACK ++ ;
  314.             tmp_tp = tmp_tp->link ;
  315.         }
  316.  
  317.         /* Count the size of STATE_STACK */
  318.  
  319.         n_sta_stack = 0 ;
  320.         tmp_tp = sta_stack ;
  321.         while (tmp_tp != NULL) {
  322.             n_sta_stack ++ ;
  323.             tmp_tp = tmp_tp->link ;
  324.         }
  325.  
  326.         /*    Put the top (n_STATE_STACK - n_sta_stack) elements of STATE_STACK
  327.          *  on the end of sta_stack
  328.          */
  329.          i = n_STATE_STACK - n_sta_stack ;
  330.          tmp_tp = STATE_STACK ;
  331.          while (--i > 0 )
  332.             tmp_tp = tmp_tp->link ;
  333.          tmp_tp->link = sta_stack ;
  334.          sta_stack = STATE_STACK ;
  335.  
  336.         reset_cands() ;
  337.         return ;
  338.  
  339.     } /* if */
  340.  
  341.     /**************************** D E L E T E *********************************/
  342.  
  343.     else if (CANDIDATES[DELETE] != NULL ) {
  344.  
  345.         /* [-, bk] := arb CANDIDATES[DELETE];                         */
  346.         /* ct = bk == 0 ? curtok : prs_stack(n_prs_stack - bk + 1) ; */
  347.  
  348.         if ((bk = CANDIDATES[DELETE]->backup_toks) == 0)
  349.             ct = copytoken(curtok) ;
  350.         else {
  351.             /* ct := prs_stack(n_prs_stack - bk + 1) ;*/ 
  352.             int    bktmp = bk ;
  353.             struct prsstack *tmp_ps = prs_stack ;
  354.  
  355.             while(--bktmp)
  356.                 tmp_ps = tmp_ps->prev ;
  357.  
  358.             ct = copytoken(tmp_ps) ;
  359.         }
  360.  
  361.         sprintf(msg, "Unexpected \"%s\" ignored", find_name(ct) ) ;
  362.         PRSERR_LOC = ct->ptr.token->span ;
  363.         syntax_err(LLOC(ct),RLOC(ct),msg);
  364.  
  365.         tokmod = NULL ;
  366.         delete_flag = 1;
  367.     } /* if */
  368.  
  369.     /************************** S U B S T ************************************/
  370.  
  371.     else if (CANDIDATES[SUBST] != NULL) {
  372.  
  373.         /* [subtk, -, bk] := arb substs; */
  374.  
  375.         tv = namelist((subtk = CANDIDATES[SUBST]->token_sym));
  376.  
  377.         /* ct = bk == 0 ? curtok : prs_stack(n_prs_stack - bk + 1) ; */
  378.  
  379.         if ((bk = CANDIDATES[SUBST]->backup_toks) == 0)
  380.             ct = copytoken(curtok) ;
  381.         else {
  382.             /* ct := prs_stack(n_prs_stack - bk + 1) */
  383.             int    bktmp = bk ;
  384.             struct prsstack *tmp_ps = prs_stack ;
  385.  
  386.             while(--bktmp)
  387.                 tmp_ps = tmp_ps->prev ;
  388.  
  389.             ct = copytoken(tmp_ps) ;
  390.         }
  391.  
  392.         PRSERR_LOC = ct->ptr.token->span ;
  393.  
  394.         /* 
  395.          * tokmod := [[subtk, get_name(token_value_des(tv) ? tv), top(ct)]];
  396.          */
  397.         tokmod = copytoken(ct) ;
  398.         tokmod->prev = NULL ;
  399.         tokmod->symbol = subtk ;
  400.         tokmod->ptr.token->index = namemap(token_val_des(tv),
  401.           strlen(token_val_des(tv))) ; 
  402.  
  403.         if (n_CANDIDATES[SUBST] == 1) {
  404.             if ( (is_reserved(CANDIDATES[SUBST]->token_sym) )
  405.               && (ct->symbol == ID_SYM) && (spell(tv,find_name(ct) ) < 3) )
  406.                 sprintf(msg,"Reserved word \"%s\" misspelled", tv) ;
  407.             else
  408.                 sprintf(msg,"\"%s\" expected instead of \"%s\"",
  409.                   tv,find_name(ct) ) ;
  410.  
  411.             syntax_err(LLOC(ct),RLOC(ct),msg);
  412.         }
  413.         else {
  414.             char    *tmp = msg;
  415.             PCAND    next_cand ;
  416.             /*
  417.              * errfile := ['{' +/[' ' + NAME_LIST(x(1)) : x in substs]
  418.              *                + ' } expected instead of ' + '"' +
  419.              *                find_name(ct) + '"'];
  420.              */
  421.             sprintf(tmp,"One of { ");
  422.             tmp += strlen(tmp);
  423.             next_cand = CANDIDATES[SUBST] ;
  424.             while(next_cand != NULL) {    
  425.                 sprintf(tmp,"%s ",namelist(next_cand->token_sym) ) ;
  426.                 tmp += strlen(tmp);
  427.                 next_cand = next_cand->next ;
  428.             }
  429.             sprintf(tmp," } expected instead of \"%s\"",find_name(ct)) ;
  430.             syntax_err(LLOC(ct),RLOC(ct),msg);
  431.         }
  432.     } 
  433.  
  434.     /*
  435.      * Alter token sequence in accordance with corrective action.
  436.      * Restore state and parse stacks to correction point.
  437.      */
  438.  
  439.     for (i = 1 ; i<=bk; i++ ) {
  440.         r = prs_stack;
  441.         prs_stack = prs_stack->prev ;
  442.         r->prev = NULL ;
  443.         add_to_top(r) ;
  444.     } 
  445.  
  446.     if (tokmod != NULL) 
  447.         tokens[tokind] = tokmod ;
  448.     else if (delete_flag)
  449.         TOKMINUS;
  450.     /* 
  451.      * STA_STACK +:= STATE_STACK(n_STA_STACK + 1 .. n_STATE_STACK - bk) ; 
  452.      */
  453.  
  454.     /*    Strip bk elements off the top off STATE_STACK    */
  455.  
  456.     while (bk--)
  457.         STATE_STACK = STATE_STACK->link ;
  458.  
  459.     /* Count the size of STATE_STACK */
  460.  
  461.     n_STATE_STACK = 0 ;
  462.     tmp_tp = STATE_STACK ;
  463.     while (tmp_tp != NULL) {
  464.         n_STATE_STACK ++ ;
  465.         tmp_tp = tmp_tp->link ;
  466.     }
  467.  
  468.     /* Count the size of STATE_STACK */
  469.  
  470.     n_sta_stack = 0 ;
  471.     tmp_tp = sta_stack ;
  472.     while (tmp_tp != NULL) {
  473.         n_sta_stack ++ ;
  474.         tmp_tp = tmp_tp->link ;
  475.     }
  476.  
  477.     /*
  478.      *    Put the top (n_STATE_STACK - n_sta_stack) elements of STATE_STACK
  479.      *  on the end of sta_stack
  480.      */
  481.      i = n_STATE_STACK - n_sta_stack ;
  482.      tmp_tp = STATE_STACK ;
  483.      while (--i > 0 )
  484.         tmp_tp = tmp_tp->link ;
  485.      tmp_tp->link = sta_stack ;
  486.      sta_stack = STATE_STACK ;
  487.  
  488.      reset_cands() ;
  489.  
  490. }    /* end procedure make_correction; */
  491.  
  492. static void reset_cands()                                    /*;reset_cands*/
  493. {
  494.     int i ;
  495.     /* 
  496.      * Reset the sets of candidates to empty for future errors 
  497.      */
  498.      for (i = DELETE ; i <= SPELL_SUBST ; i ++ ) 
  499.      {
  500.         n_CANDIDATES[i] = 0 ;
  501.         CANDIDATES[i] = NULL ;
  502.      }
  503. }
  504.